//
//  TrackpadView.swift
//  iTrackpad
//
//  Created by lbxia on 2021/9/16.
//

import UIKit

enum TouchStatus  {
    case begin
    case move
    case end
    case cancel
}

class TrackpadView: UIView {

    //单个手指单击
    var tapGesture : UITapGestureRecognizer?
    //单个手指双击
    var tapDoubleGesture : UITapGestureRecognizer?

    var rightTapGesture : UITapGestureRecognizer?
    
    var touchStatus : TouchStatus = .end
    //移动过
//    var moving : Bool = false

    //根据设置的手指头数量来决定
    var scrollXing : Bool = false
    var scrollYing : Bool = false
    
    //记录时间，这样可以判断操作的速度，以及最后是否停止后才抬起的手指，这样计算是否有惯性以及惯性大小，经测试计算最后5个数据即可？
    var historyScrollDate: [Date] = []
    var historyScrollPos: [CGPoint] = []
    
    
    //记录移动过程中手指的个数  手指数量在各个事件之间可能会不一致，多个手指触摸时，因为每个手指接触或抬起时间有细微差别
    //在end事件时 可以通过大部分手指数量来确定具体功能
    var historyMovetouches : [Int] = []
    
    var begionPt : CGPoint = CGPoint(x: 0, y: 0)
    
    //可能手指不是同时按下，这样还为end事件，会有顺序触发多次begin事件
    var beginNums : Int = 0
    var beginDate : Date = Date()
    
    //统计结束的手指数量,有可能多个手指非同时抬起
    var endNums : Int = 0
    

    
    func start()  {
        //开启多点触摸
        self.isMultipleTouchEnabled = true
        
//        if (tapGesture == nil) {
//            self.tapGesture = UITapGestureRecognizer(target: self, action: #selector(leftClick))
//
//        }
//        self .addGestureRecognizer(self.tapGesture!)
//
//        if (rightTapGesture == nil) {
//            self.rightTapGesture = UITapGestureRecognizer(target: self, action: #selector(rightClick))
//            self.rightTapGesture?.numberOfTouchesRequired = 2
//
//        }
//        self .addGestureRecognizer(self.rightTapGesture!)
        
    }
    
    func stop() {
        
        if let gesture = self.tapGesture {
            self.removeGestureRecognizer(gesture)
        }
    }
    
    
    @objc func leftClick()  {
        
        print("leftclick")
        
    }
    
    @objc func rightClick()  {
        
        print("rightclick")
    }
    
    /*
     手指数量在各个事件之间可能会不一致，多个手指触摸时，因为每个手指接触或抬起时间有细微差别
     */
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        
        let count = touches.count
        
        print("touch begin count:\(count)")
        
        self.touchStatus = .begin
        
        if self.beginNums == 0 {
            //记录首次开始触控时间
            self.beginDate = Date()
        }
        self.beginNums += count
        
        for touch:AnyObject in touches {

            let point = (touch as AnyObject).location(in: self)

            //单击操作，需要用到位置比较
            self.begionPt = point;
        }

    }
    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        
        let count = touches.count
        print("touch move count:\(count)")

        
        self.touchStatus = .move
        self.historyMovetouches.append(count)
        
        let point = (touches[touches.startIndex] as AnyObject).location(in: self)
        self.historyScrollDate.append(Date())
        self.historyScrollPos.append(point)       
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        
        if self.touchStatus == .end {
            return
        }
        
        var count = touches.count

        print("touchesEnded:\(count)")

        if self.beginNums != (count + self.endNums ) {
            self.endNums += count
            return
        }
        
        
        /*
         测试问题记录
         
         2指
         touch begin count: 2
         touchesEnded:1
         leftclick
         touchesEnded:1
         
         
         //2个手指非同时按下，抬起也非同时抬起
         touch begin count: 1
         touch begin count: 1
         touchesEnded:1
         leftclick
         touchesEnded:1
         
         //2个手指非同时按下，但是同时抬起
         touch begin count: 1
         touch begin count: 1
         touchesEnded:2
         rightclick
         
         测试发现苹果触控板2指右键，时间延时比较长，不太理想，可能有其他坑，所以没办法？
         
         触控板支持： 一个手指用力按下，另外一个手指移动，达到拖拽，或者编辑状态 选择功能 (和三指移动类似效果)
         */
        
        //计算出现手指数量，不以最后end为准，算历史
        if self.historyMovetouches.count > 0 {
            
            //正常最多5个手指
            var tongji = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
            for num in self.historyMovetouches {
                tongji[num] += 1
            }
            var maxNum = 0
            var maxfrequencyCount = 0
            for (idx,tongjiItem) in tongji.enumerated() {
                if tongjiItem > maxNum {
                    maxNum = tongjiItem
                    maxfrequencyCount = idx
                }
            }
            
            if maxNum > 1 {
                
                print("计算出现手指次数，来判断最终结果 count:\(count) maxfrequencyCount:\(maxfrequencyCount)")
                //出现最多次
                count = maxfrequencyCount
            }
        }
        else{
        
            if self.beginNums == 2 && count == 1 {
                count = 2
            }
            
        }
        
        if count == 1 {
            //单指  点击，移动，双击
            if self.touchStatus != .move {
                
                let point = (touches[touches.startIndex] as AnyObject).location(in: self)

                if abs(point.x - self.begionPt.x) < 5 && abs(point.y - self.begionPt.y) < 5  {
                    self.leftClick()
                }else{
                    
                    //print( "click diffx:\(point.x - self.begionPt.x) diffy:\(point.y - self.begionPt.y)" )
                }
            }
            
        }
        else if count == 2 {
            //双指, 点击右键，scroll
            
            if self.touchStatus != .move {
                
                //计算时间间隔，过长不做任何处理
                if Date().timeIntervalSince(self.beginDate) < 0.3 {
                    /*
                     实际使用trackpad触控板2个手指间隔很远，一样是打开右键功能，这样不用计算触摸坐标范围
                     2个手指前后有稍微的间隔时间操作，也是当作右键，所以这里通过算法计算手指数量完全能模拟触控板效果
                     */
                    self.rightClick()
                }
                else{
                    print("双指按下时间过长")
                }
               
            }else{
                
                //TODO: 计算scroll惯性
                
                let tmpHistory = self.historyScrollDate
                let tmpHistoryPos = self.historyScrollPos
                
                if tmpHistory.count > 5 {
                    
                    let maxComputeCount = tmpHistory.count > 7 ? 7 : tmpHistory.count
                    var totalDiffTime = 0.0
                    var totalDiffPos : CGFloat = 0.0;
                    
                    let maxIndex = tmpHistory.count - 1
                    
                    var preDate = tmpHistory[maxIndex]
                    for idx in 1...maxComputeCount-1{
                        let date = tmpHistory[maxIndex-idx];
                        let diff = preDate.timeIntervalSince(date)
                        //                print("diff:\(diff)")
                        totalDiffTime += diff
                        preDate = date
                    }
                    
                    var prePt = tmpHistoryPos[maxIndex]
                    for idx in 1...maxComputeCount-1{
                        let pt = tmpHistoryPos[maxIndex-idx];
                        let diff = prePt.y - pt.y
                        //                print("diffpos:\(diff)")
                        totalDiffPos += diff
                        prePt = pt
                    }
                    
                    //diffpos越大, diffTime越小则惯性越大，需要多测试总结经验值
                    print("total \(maxComputeCount) diffTime:\(totalDiffTime) diffPos:\(totalDiffPos)")
                    
                    if totalDiffPos > 60 && totalDiffTime < 0.0999 {
                        print("compute decide scroll")
                    }
                }
            }
            
        }else if count == 3 {
            //3指，拖拽，一般移动文件，编辑器内选择内容，app移动窗口等
            //在move事件内处理
            
        }else if count == 4 {
            //4指，上下，左右
        }
        
        
//        for touch:AnyObject in touches {
//
//            let point = (touch as AnyObject).location(in: self)
//        }
            
          
        self.resetStatus()
        
    }
    
    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        
       self .resetStatus()
    }
    
    func resetStatus()  {
        
        self.touchStatus = .end
        self.beginNums = 0
        self.endNums = 0
        self.historyScrollDate.removeAll()
        self.historyScrollPos.removeAll()
        self.historyMovetouches.removeAll()
    }

}
